package com.xwltz.core.utils.json;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.text.SimpleDateFormat;

/**
 * @description JacksonUtils
 * @information on version 1.0 be created by @xwltz at 2021/11/29 16:54
 */
@SuppressWarnings("unchecked")
public class JacksonUtils {
	private static final Log log = LogFactory.get();

	private static final ObjectMapper objectMapper = new ObjectMapper();
	private static final String STANDARD_FORMAT = "yyyy-MM-dd HH:mm:ss";

	static {
		//对象的所有字段全部列入
		objectMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);
		//取消默认转换timestamps形式
		objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
		//忽略空Bean转json的错误
		objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
		//所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
		objectMapper.setDateFormat(new SimpleDateFormat(STANDARD_FORMAT));
		//忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
		objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

	/**
	 * 对象转Json格式字符串
	 *
	 * @param obj 对象
	 * @return Json格式字符串
	 */
	public static <T> String toJson(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			log.warn("Parse Object to String error : {}", e.getMessage());
			return null;
		}
	}

	/**
	 * 对象转Json格式字符串(格式化的Json字符串)
	 *
	 * @param obj 对象
	 * @return 美化的Json格式字符串
	 */
	public static <T> String toJsonPretty(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
		} catch (JsonProcessingException e) {
			log.warn("Parse Object to String error : {}", e.getMessage());
			return null;
		}
	}

	/**
	 * 字符串转换为自定义对象
	 *
	 * @param str   要转换的字符串
	 * @param clazz 自定义对象的class对象
	 * @return 自定义对象
	 */
	public static <T> T toObject(String str, Class<T> clazz) {
		if (!StringUtils.hasLength(str)) {
			return null;
		}
		try {
			return clazz.equals(String.class) ? (T) str : objectMapper.readValue(str, clazz);
		} catch (Exception e) {
			log.warn("Parse String to Object error : {}", e.getMessage());
			return null;
		}
	}

	public static <T> T toObject(String str, TypeReference<T> typeReference) {
		if (StringUtils.hasLength(str) || typeReference == null) {
			return null;
		}
		try {
			return (T) (typeReference.getType().equals(String.class) ? str : objectMapper.readValue(str, typeReference));
		} catch (IOException e) {
			log.warn("Parse String to Object error", e);
			return null;
		}
	}

	public static <T> T toObject(String str, Class<?> collectionClazz, Class<?>... elementClazzes) {
		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionClazz, elementClazzes);
		try {
			return objectMapper.readValue(str, javaType);
		} catch (IOException e) {
			log.warn("Parse String to Object error : {}" + e.getMessage());
			return null;
		}
	}
}
